import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;


public class PanelClickHandler implements MouseListener, MouseMotionListener {
	
	Main main_delegate;
	Panel panel_delegate;
	
	Point pointBuffer = null;
	//TO-DO state buffer should be reset to -1 every time the state changes
	public int stateBuffer = -1;
	
	public PanelClickHandler(Main $main_delegate, Panel $panel_delegate){
		main_delegate = $main_delegate;
		panel_delegate = $panel_delegate;
	}
	
	public boolean checkList(MouseEvent arg0){
		
		Point p = panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList);
		if(p.x == -1){
			return false;
		}
		
		Point pL = panel_delegate.getLastPoint();
		if(pL.x == p.x && p.y == pL.y)
			return false;
		
		return true;
	}

	public void stateUpdate(int state){
		stateBuffer = state;
	}
	
	public boolean stateChange(int state){
		if(stateBuffer == state){
			return false;
		}
		return true;
	}
	
	@Override
	public void mouseClicked(MouseEvent arg0) {
		
		panel_delegate.repaint();
		
		if(stateChange(main_delegate.state)){//state changed - reset pointBuffer
			pointBuffer = null;
		}
		if(!panel_delegate.closedLoop)
		switch(main_delegate.state){
		
			case StateList.NEW_POINT:
				Point doublePointBuffer = panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList);
				if(doublePointBuffer.x == -1){
					pointBuffer = doublePointBuffer;
					panel_delegate.newPoint(new Point(arg0.getX(), arg0.getY(),panel_delegate));
				}
				break;
				
				
			case StateList.REMOVE_POINT:
				
				System.out.println("Finding Point");
				pointBuffer = panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList);
				
				if(pointBuffer.x != -1){
					panel_delegate.removePoint(pointBuffer);
					System.out.println("found : Removing point");				
				}else {
					System.out.println("not found");
				}
				break;
				
				
			case StateList.CONNECT_POINTS:
				
				//case: 
				//	invalid point - state updated  === HANDLED BY : updating pointBuffer to null on 2nd point; expect pointBuffer null on first point
				
				//3 conditions
				//	- point must exist
				//	- 2 cases point is second or first point
				//		- state buffer must match state
				//		- pointBuffer is null on first point
				
				//point buffer is only ever set back to null when the second point has been selected || state changes
				
				if(checkList(arg0)){ //point exists
					
					if(pointBuffer == null){//first point
						
						pointBuffer =  panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList);
						
					} else {//second point

						
						panel_delegate.connectPoints(pointBuffer,panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList));
						pointBuffer = null;
						
					}
					
				} else {
					panel_delegate.invalidPoint();
				}
				
				break;
				
				
				
			case StateList.REMOVE_LINE://to remove a line select both points
				
				//see CONNECT_POINT notes
				
				if(checkList(arg0)){ //point exists
					
					if(pointBuffer == null){//first point
						
						pointBuffer =  panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList);
						
					} else {//second point

						
						panel_delegate.removeLine(pointBuffer,panel_delegate.findPoint(new Point(arg0.getX(),arg0.getY(),panel_delegate),panel_delegate.pointList));
						pointBuffer = null;
						
					}
					
				} else {
					panel_delegate.invalidPoint();
				}
					
				
				
				
				break;
				
				
			case StateList.SEQUENCE:
				
				if(pointBuffer != null)
					System.out.println("buffer ("+pointBuffer.x+","+pointBuffer.y+")");
				
				Point p = new Point(arg0.getX(),arg0.getY(),panel_delegate);
				
				//add point -- newPoint will check validity of point
				panel_delegate.newPoint(p);
				
				if(checkList(arg0)){//successfully added to list connect with previous point
					//if(pointBuffer != null){
					//	System.out.println("Buffer isn't null");
					//	panel_delegate.connectPoints(p, pointBuffer);
					//}else{
						panel_delegate.connectPoints(p,panel_delegate.getLastPoint());
						System.out.println("Get last point");
					//}
				}
				
				pointBuffer = p;				
								
				break;
			case StateList.FREE_HAND:
				//TO-DO
				break;
			
			
		}
				

			stateUpdate(main_delegate.state);
				
				
		}
		
		
	
	@Override
	public void mouseEntered(MouseEvent arg0) {
		System.out.println("Mouse Entered");
		
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseExited(MouseEvent arg0) {
		System.out.println("Mouse Exited");
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mousePressed(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseReleased(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

}
